// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2023, Huaihan He <hehuaihan@huawei.com>
 */

#ifndef QCOM_SUBSYS_NOTIFY_H
#define QCOM_SUBSYS_NOTIFY_H

#include <linux/remoteproc.h>
#include <linux/string.h>
#include <linux/of_platform.h>
#include <linux/notifier.h>
#include <linux/delay.h>
#include <linux/mutex.h>

#ifdef CONFIG_QCOM_SUBSYS_NOTIFY_ADAPT
#define STATIC
#else
#define STATIC static
#endif

/** enum subsystem notifiers
 * @SUBSYS_BEFORE_SHUTDOWN remoteproc is about to get powerdown
 * @SUBSYS_AFTER_SHUTDOWN remoteproc shutdown is complete
 * @SUBSYS_BEFORE_POWERUP remoteproc is about to get power up
 * @SUBSYS_AFTER_POWERUP remoteproc power up is complete
 * @SUBSYS_RAMDUMP_NOTIFICATION ramdump can be collected
 * @SUBSYS_POWERUP_FAILURE power up failed
 * @SUBSYS_PREPARE_FOR_FATAL_SHUTDOWN remoteproc fatal exception receivced
 */

enum subsys_notif_type {
	SUBSYS_BEFORE_SHUTDOWN,
	SUBSYS_AFTER_SHUTDOWN,
	SUBSYS_BEFORE_POWERUP,
	SUBSYS_AFTER_POWERUP,
	SUBSYS_RAMDUMP_NOTIFICATION,
	SUBSYS_POWERUP_FAILURE,
	SUBSYS_PROXY_VOTE,
	SUBSYS_PROXY_UNVOTE,
	SUBSYS_SOC_RESET,
	SUBSYS_PREPARE_FOR_FATAL_SHUTDOWN,
	SUBSYS_NOTIF_TYPE_COUNT
};

struct mutex *get_rproc_list_mutex(void);
struct list_head *get_rproc_list(void);
struct rproc *rproc_get_by_name(const char *name);
int rproc_register_subsys_notifier(const char *name, struct notifier_block *nb,
		struct notifier_block *atomic_nb);
int rproc_unregister_subsys_notifier(const char *name, struct notifier_block *nb,
		struct notifier_block *atomic_nb);

#ifdef CONFIG_QCOM_SUBSYS_NOTIFY_ADAPT
extern void rproc_subsys_notify(struct rproc *rproc, int event, bool atomic);
extern void rproc_notifier_head_init(struct rproc *rproc);
#else
static inline void rproc_subsys_notify(struct rproc *rproc, int event, bool atomic) {}
static inline void rproc_notifier_head_init(struct rproc *rproc) {}
#endif

#endif /* QCOM_SUBSYS_NOTIFY_H */
